#include <microhttpd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <json-c/json.h>
#include <stdbool.h>
#include <alsa/asoundlib.h>
#include <ctype.h>
#define PAGE "<html><head><meta charset=\"UTF-8\"><title>音频控制面板</title>"                                                                                                                                                                                                 \
             "<style>"                                                                                                                                                                                                                                                               \
             "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #e0f7fa; margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; }"                                                                                    \
             ".container { width: 100%; max-width: 500px; background: #ffffff; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); overflow: hidden; }"                                                                                                                      \
             "header { background: #00796b; color: #ffffff; padding: 20px; text-align: center; border-top-left-radius: 10px; border-top-right-radius: 10px; }"                                                                                                                       \
             ".content { padding: 20px; }"                                                                                                                                                                                                                                           \
             "h1 { margin: 0; font-size: 24px; }"                                                                                                                                                                                                                                    \
             "h2 { color: #00796b; font-size: 18px; margin-top: 20px; }"                                                                                                                                                                                                             \
             ".button { display: inline-block; padding: 10px 20px; margin: 10px 5px; background-color: #00796b; color: #ffffff; border: none; border-radius: 5px; cursor: pointer; text-align: center; text-decoration: none; font-size: 16px; transition: background-color 0.3s; }" \
             ".button:hover { background-color: #004d40; }"                                                                                                                                                                                                                          \
             "input[type='range'] { width: 100%; margin: 10px 0; }"                                                                                                                                                                                                                  \
             "</style>"                                                                                                                                                                                                                                                              \
             "<script>"                                                                                                                                                                                                                                                              \
             "function sendRequest(action, value) {"                                                                                                                                                                                                                                 \
             "  fetch('/' + action, { method: 'POST', body: JSON.stringify({value: value}) })"                                                                                                                                                                                       \
             "    .then(response => response.text())"                                                                                                                                                                                                                                \
             "    .then(data => alert(data));"                                                                                                                                                                                                                                       \
             "}"                                                                                                                                                                                                                                                                     \
             "</script>"                                                                                                                                                                                                                                                             \
             "</head><body>"                                                                                                                                                                                                                                                         \
             "<div class=\"container\">"                                                                                                                                                                                                                                             \
             "<header><h1>音频控制面板</h1></header>"                                                                                                                                                                                                                          \
             "<div class=\"content\">"                                                                                                                                                                                                                                               \
             "<h2>扬声器控制</h2>"                                                                                                                                                                                                                                              \
             "<button class=\"button\" onclick=\"sendRequest('speaker_on')\">打开扬声器</button>"                                                                                                                                                                               \
             "<button class=\"button\" onclick=\"sendRequest('speaker_off')\">关闭扬声器</button>"                                                                                                                                                                              \
             "<input type=\"range\" min=\"0\" max=\"100\" value=\"50\" id=\"speakerVolume\">"                                                                                                                                                                                        \
             "<button class=\"button\" onclick=\"sendRequest('speaker_volume', document.getElementById('speakerVolume').value)\">设置扬声器音量</button>"                                                                                                                     \
             "<h2>麦克风控制</h2>"                                                                                                                                                                                                                                              \
             "<button class=\"button\" onclick=\"sendRequest('mic_on')\">打开麦克风</button>"                                                                                                                                                                                   \
             "<button class=\"button\" onclick=\"sendRequest('mic_off')\">关闭麦克风</button>"                                                                                                                                                                                  \
             "<input type=\"range\" min=\"0\" max=\"100\" value=\"50\" id=\"micVolume\">"                                                                                                                                                                                            \
             "<button class=\"button\" onclick=\"sendRequest('mic_volume', document.getElementById('micVolume').value)\">设置麦克风音量</button>"                                                                                                                             \
             "</div>"                                                                                                                                                                                                                                                                \
             "</div>"                                                                                                                                                                                                                                                                \
             "</body></html>"

int set_capture_switch(const char *card, const char *selem, bool enable)
{
    int err;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0)
    {
        fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err));
        return err;
    }
    // 把混音器设备附加到声卡
    // 附加控制接口到混音器
    if ((err = snd_mixer_attach(handle, card)) < 0)
    {
        fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0)
    {
        fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0)
    {
        fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);

    // 设置简单元素的名称
    snd_mixer_selem_id_set_name(sid, selem);

    // 查找简单元素
    snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
    if (!elem)
    {
        fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0);
        snd_mixer_close(handle);
        return -ENOENT;
    }

    // 设置采集开关（启用或禁用）
    if ((err = snd_mixer_selem_set_capture_switch_all(elem, enable ? 1 : 0)) < 0)
    {
        fprintf(stderr, "Unable to set capture switch: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);

    return 0; // 成功
}

// 设置音频回放开关的函数
// card: 声卡名称
// selem: 控制项名称
// enable: 开关状态
int set_playback_switch(const char *card, const char *selem, bool enable)
{
    int err;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0)
    {
        fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err));
        return err;
    }

    // 附加控制接口到混音器
    if ((err = snd_mixer_attach(handle, card)) < 0)
    {
        fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0)
    {
        fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0)
    {
        fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);

    // 设置简单元素的名称
    snd_mixer_selem_id_set_name(sid, selem);

    // 查找简单元素
    snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
    if (!elem)
    {
        fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0);
        snd_mixer_close(handle);
        return -ENOENT;
    }

    // 设置回放开关（启用或禁用）
    if ((err = snd_mixer_selem_set_playback_switch_all(elem, enable ? 1 : 0)) < 0)
    {
        fprintf(stderr, "Unable to set playback switch: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);

    return 0; // 成功
}

// 获取音频采集音量
// card: 声卡名称
// selem: 控制项名称
// 返回值: 当前音量
int get_capture_volume(const char *card, const char *selem)
{
    int err;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0)
    {
        fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err));
        return err;
    }

    // 附加控制接口到混音器
    if ((err = snd_mixer_attach(handle, card)) < 0)
    {
        fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0)
    {
        fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0)
    {
        fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);

    // 设置简单元素的名称
    snd_mixer_selem_id_set_name(sid, selem);

    // 查找简单元素
    snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
    if (!elem)
    {
        fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0);
        snd_mixer_close(handle);
        return -ENOENT;
    }

    // 获取采集通道音量
    long volume = 0;
    if ((err = snd_mixer_selem_get_capture_volume(elem, 0, &volume)) < 0)
    {
        fprintf(stderr, "Unable to get capture volume: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);

    return volume; // 成功返回音量
}

// 获取音频回放通道音量
// card: 声卡名称
// selem: 控制项名称
// 返回值: 当前音量
int get_playback_volume(const char *card, const char *selem)
{
    int err;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0)
    {
        fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err));
        return err;
    }

    // 附加控制接口到混音器
    if ((err = snd_mixer_attach(handle, card)) < 0)
    {
        fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0)
    {
        fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0)
    {
        fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);

    // 设置简单元素的名称
    snd_mixer_selem_id_set_name(sid, selem);

    // 查找简单元素
    snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
    if (!elem)
    {
        fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0);
        snd_mixer_close(handle);
        return -ENOENT;
    }

    // 获取回放通道音量
    long volume = 0;
    if ((err = snd_mixer_selem_get_playback_volume(elem, 0, &volume)) < 0)
    {
        fprintf(stderr, "Unable to get playback volume: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);

    return volume; // 成功返回音量
}

// 设置音频采集音量
// card: 声卡名称
// selem: 控制项名称
// volume: 设置音量
// 返回值: 成功返回设置后的音量，失败返回错误码
int set_capture_volume(const char *card, const char *selem, long volume)
{
    int err;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0)
    {
        fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err));
        return err;
    }

    // 附加控制接口到混音器
    if ((err = snd_mixer_attach(handle, card)) < 0)
    {
        fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0)
    {
        fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0)
    {
        fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);

    // 设置简单元素的名称
    snd_mixer_selem_id_set_name(sid, selem);

    // 查找简单元素
    snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
    if (!elem)
    {
        fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0);
        snd_mixer_close(handle);
        return -ENOENT;
    }

    // 获取音量范围
    long min, max;
    if ((err = snd_mixer_selem_get_capture_volume_range(elem, &min, &max)) < 0)
    {
        fprintf(stderr, "Unable to get capture volume range: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    if (volume < min)
    {
        volume = min;
    }

    if (volume > max)
    {
        volume = max;
    }

    // 设置采集通道音量
    if ((err = snd_mixer_selem_set_capture_volume_all(elem, volume)) < 0)
    {
        fprintf(stderr, "Unable to set capture volume: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);

    return volume; // 成功
}

// 设置音频回放通道音量
// card: 声卡名称
// selem: 控制项名称
// volume: 设置音量
// 返回值: 成功返回设置后的音量，失败返回错误码
int set_playback_volume(const char *card, const char *selem, long volume)
{
    int err;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;

    // 打开混音器
    if ((err = snd_mixer_open(&handle, 0)) < 0)
    {
        fprintf(stderr, "Mixer %s open error: %s\n", card, snd_strerror(err));
        return err;
    }

    // 附加控制接口到混音器
    if ((err = snd_mixer_attach(handle, card)) < 0)
    {
        fprintf(stderr, "Mixer attach %s error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 注册混音器
    if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0)
    {
        fprintf(stderr, "Mixer register error: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 加载混音器元素
    if ((err = snd_mixer_load(handle)) < 0)
    {
        fprintf(stderr, "Mixer %s load error: %s\n", card, snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 分配简单元素ID
    snd_mixer_selem_id_alloca(&sid);

    // 设置简单元素的名称
    snd_mixer_selem_id_set_name(sid, selem);

    // 查找简单元素
    snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
    if (!elem)
    {
        fprintf(stderr, "Unable to find simple control '%s',%i\n", selem, 0);
        snd_mixer_close(handle);
        return -ENOENT;
    }

    // 获取音量范围
    long min, max;
    if ((err = snd_mixer_selem_get_playback_volume_range(elem, &min, &max)) < 0)
    {
        fprintf(stderr, "Unable to get playback volume range: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    if (volume < min)
    {
        volume = min;
    }

    if (volume > max)
    {
        volume = max;
    }

    // 设置回放通道音量
    if ((err = snd_mixer_selem_set_playback_volume_all(elem, volume)) < 0)
    {
        fprintf(stderr, "Unable to set playback volume: %s\n", snd_strerror(err));
        snd_mixer_close(handle);
        return err;
    }

    // 关闭混音器
    snd_mixer_close(handle);

    return volume; // 成功返回设置后音量
}

bool is_number(const char *str)
{
    for (int i = 0; str[i] != '\0'; i++)
    {
        if (!isdigit(str[i]))
        {
            return false;
        }
    }
    return true;
};

static int ahc_echo(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version,
                    const char *upload_data, size_t *upload_data_size, void **ptr)
{
    static int dummy;
    struct MHD_Response *response;
    int ret;
    const char *device = "hw:0";

    if (&dummy != *ptr)
    {
        *ptr = &dummy;
        return MHD_YES;
    }

    if (0 == strcmp(method, "GET"))
    {
        // 处理 GET 请求，返回页面
        response = MHD_create_response_from_buffer(strlen(PAGE), (void *)PAGE, MHD_RESPMEM_PERSISTENT);
    }
    else if (0 == strcmp(method, "POST"))
    {
        // 处理 POST 请求，根据 URL 执行不同的操作
        const char *response_text;
        if (0 == strcmp(url, "/speaker_on"))
        {
            set_playback_switch(device, "Master", true);
            set_playback_switch(device, "PCM", true);
            response_text = "扬声器已打开";
        }
        else if (0 == strcmp(url, "/speaker_off"))
        {
            set_playback_switch(device, "Master", false);
            set_playback_switch(device, "PCM", false);
            response_text = "扬声器已关闭";
        }
        else if (0 == strcmp(url, "/mic_on"))
        {
            set_capture_switch(device, "Capture", true);
            response_text = "麦克风已打开";
        }
        else if (0 == strcmp(url, "/mic_off"))
        {
            set_capture_switch(device, "Capture", false);
            response_text = "麦克风已关闭";
        }
        else if (0 == strcmp(url, "/speaker_volume") || 0 == strcmp(url, "/mic_volume"))
        {
            // 解析 JSON 数据
            struct json_object *parsed_json;
            struct json_object *value_obj;

            parsed_json = json_tokener_parse(upload_data);
            json_object_object_get_ex(parsed_json, "value", &value_obj);
            int volume = json_object_get_int(value_obj);

            char volume_str[20];
            if (0 == strcmp(url, "/speaker_volume"))
            {
                snprintf(volume_str, sizeof(volume_str), "扬声器音量设置为 %d", set_playback_volume(device, "Master", volume));
            }
            else
            {
                snprintf(volume_str, sizeof(volume_str), "麦克风音量设置为 %d", set_capture_volume(device, "Capture", volume));
            }
            response_text = volume_str;

            json_object_put(parsed_json);
        }
        else
        {
            response_text = "未知操作";
        }
        response = MHD_create_response_from_buffer(strlen(response_text), (void *)response_text, MHD_RESPMEM_PERSISTENT);
    }
    else
    {
        return MHD_NO; // 不支持的方法
    }

    ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
    MHD_destroy_response(response);
    return ret;
}

int main(int argc, char **argv)
{
    struct MHD_Daemon *d;
    if (argc != 2)
    {
        printf("%s PORT\n", argv[0]);
        return 1;
    }
    d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, atoi(argv[1]), NULL, NULL,
                         (MHD_AccessHandlerCallback)&ahc_echo, PAGE, MHD_OPTION_END);
    if (d == NULL)
        return 1;
    (void)getc(stdin);
    MHD_stop_daemon(d);
    return 0;
}
